<!-- 媒体预览组件 -->
<template>
  <a-modal
    :open="visible"
    :footer="null"
    width="988px"
    wrap-class-name="preview-modal"
    :body-style="{ borderRadius: '4px', padding: '8px' }"
    @cancel="handleCancel"
  >
    <template #title>
      <div class="modalTitle" :title="modalOptions?.title">{{ modalOptions?.title }}</div>
    </template>
    <div class="example">
      <div v-if="modalOptions?.type === 'image'" class="preview-image">
        <img :src="modalOptions?.url" />
      </div>
      <div v-else-if="modalOptions?.type === 'video'" class="videoPre">
        <video
          v-if="modalOptions?.url"
          :src="modalOptions?.url"
          controls
          style="width: 100%"
          autoplay
          muted
          disablePictureInPicture="true"
          @error="onVideoError"
          @play="onVideoPlay"
        ></video>
      </div>
      <pre v-else-if="modalOptions?.type === 'text'" class="preview-text p-4" v-html="modalOptions?.text"></pre>
      <p v-if="errorMsg" :class="['show-error-msg']">{{ errorMsg }}</p>
      <div v-if="modalOptions?.type === 'image'" class="footer">
        <a-button type="text" style="width: 36px" class="icon-only-btn" @click="() => setVisible(true)">
          <i class="iconfont icon-fullscreen-line"></i>
        </a-button>
      </div>
    </div>
  </a-modal>
  <div v-show="imagePreviewVisible">
    <a-image
      :style="{ display: 'none' }"
      :preview="{
        visible: imagePreviewVisible,
        onVisibleChange: setVisible
      }"
      :src="modalOptions?.url"
    />
  </div>
</template>

<script setup lang="ts">
  import { reactive, ref } from 'vue'

  export type PreviewType = 'image' | 'video' | 'text'
  export interface PreviewModalOptions {
    // 标题
    title?: string
    // 链接地址
    url?: string
    // 文本内容
    text?: string
    // 预览类型
    type: PreviewType
  }

  const emit = defineEmits(['ok', 'cancel'])

  const visible = ref(false)
  const loading = ref(false)
  const errorMsg = ref<string | undefined>(undefined)
  const modalOptions = reactive<PreviewModalOptions>({
    type: 'image',
    url: '',
    title: '图片预览'
    // type: 'video',
    // url: 'http://192.168.16.9:30256/atp-task/atp/data/1711589561764196353/1711589588930703361/%E5%A4%9A%E7%A7%8D%E7%99%BB%E5%BD%95%E6%96%B9%E5%BC%8F.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=SP3vv4pUruhUXG7Fpqzk%2F20231020%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20231020T035147Z&X-Amz-Expires=1800&X-Amz-SignedHeaders=host&X-Amz-Signature=005b5c724377c242798ebbf337a8c98badb8c7b63bba327884c26dc8e9e7dd50'
    // type: 'text',
    // text: '测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字'
  })

  const handleCancel = () => {
    hide()
    emit('cancel')
  }

  const open = (options: PreviewModalOptions) => {
    errorMsg.value = undefined
    visible.value = true
    Object.assign(modalOptions, options)

    console.log(modalOptions.text)
  }

  const hide = () => {
    errorMsg.value = undefined
    loading.value = false
    visible.value = false
  }

  const imagePreviewVisible = ref<boolean>(false)
  const setVisible = (value: boolean): void => {
    imagePreviewVisible.value = value
  }

  const changeLoading = (status: boolean) => {
    loading.value = status
  }

  const onVideoPlay = () => {
    errorMsg.value = undefined
  }

  const onVideoError = (event: any) => {
    const video = event.target as HTMLVideoElement
    switch (video.error?.code) {
      case video.error?.MEDIA_ERR_ABORTED:
        errorMsg.value = '用户放弃视频下载'
        break
      case video.error?.MEDIA_ERR_NETWORK:
        errorMsg.value = '预览视频时发生网络错误'
        break
      case video.error?.MEDIA_ERR_DECODE:
        errorMsg.value = '视频解码失败或视频格式不支持'
        break
      case video.error?.MEDIA_ERR_SRC_NOT_SUPPORTED:
        errorMsg.value = '浏览器暂不支持预览此解码格式视频'
        break
      default:
        errorMsg.value = '发生未知错误'
        break
    }
  }

  defineExpose({
    changeLoading,
    open,
    hide
  })
</script>

<style lang="less" scoped>
  .example {
    position: relative;
    overflow: hidden;
    height: 720px;
    background: #f5f5f5;
    border: 1px solid @border3;
    border-radius: 4px;

    .preview-image {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
    }

    img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    .show-error-msg {
      position: absolute;
      inset: 0;
      margin: auto;
      // width: 250px;
      height: 50px;
      text-align: center;
      color: white;
      line-height: 50px;
    }

    .videoPre {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      background-color: #f2f3f5;
    }

    .preview-text {
      box-sizing: border-box;
      overflow-x: auto;
      padding: 8px;
      margin: 0;
      width: 100%;
      height: 100%;
    }

    .footer {
      position: absolute;
      bottom: 0;
      left: 0;
      display: flex;
      justify-content: flex-end;
      padding: 0 8px;
      width: 100%;
      height: 0;
      background: @text03;
      opacity: 0;
      transition: all 0.5s ease-out;

      .icon-only-btn {
        color: #fff;
      }
    }

    &:hover {
      .footer {
        height: 34px;
        opacity: 1;
      }
    }
  }

  .modalTitle {
    width: 100%;
    .elliptical-1();
  }
</style>
